﻿using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Windows.Networking.Connectivity;
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
using XcoAppSpaces.Contracts.Worker;
using XcoAppSpaces.Core;
using XcoAppSpaces.Core.Ports;
using XcoAppSpaces.Contracts.Exceptions;
using XcoAppSpaces.Core.Configuration;
using XcoAppSpaces.Transport.Sockets;
using System.Net;

namespace test.XcoAppSpaces.Core
{
	#region Test Worker and Contract
	public class TestWorkerContract : PortSet<int, string, PortSet<int, string>, bool>
	{
		public AutoResetEvent are = new AutoResetEvent(false);
	}

	class MyTestWorker : TestWorkerContract
	{
		public int intMsg;
		public string strMsg;

		[XcoExclusive]
		public void ProcessInt(int msg)
		{
			this.intMsg = msg;
		}

		[XcoConcurrent]
		public void ProcessString(string msg)
		{
			this.strMsg = msg;
		}

		[XcoConcurrent]
		public void ProcessPort(PortSet<int, string> msg)
		{
			msg.Post(intMsg); //post back last posted integer
		}

		[XcoConcurrent]
		public void ProcessBool(bool msg)
		{
			base.are.Set();
		}
	}

	#endregion

	[TestClass]
	public class testXcoAppSpace
	{
		private int port1;
		private int port1b;
		private int port2;
		private int port3;
		private string spaceAddress1;
		private string spaceAddress1b;
		private string spaceAddress2;
		private string spaceAddress3;
		private string testWorkerName;

		[TestInitialize]
		public void Setup()
		{
			port1 = 8001;
			port1b = 9001;
			port2 = 8002;
			port3 = 8003;
			string hostname = "localhost"; //NetworkInformation.GetHostNames().First().DisplayName;
			spaceAddress1 = hostname + ":" + port1;
			spaceAddress1b = hostname + ":" + port1b;
			spaceAddress2 = hostname + ":" + port2;
			spaceAddress3 = hostname + ":" + port3;
			testWorkerName = "testworker";
		}


		[TestMethod]
		public void TestInstantiateLocal()
		{
			using (XcoAppSpace space = new XcoAppSpace())
			{
				Assert.IsNull(space.Address);
			}
		}

		[TestMethod]
		public void TestWorkerLocalAndRemote1()
		{
			TestWorkerLocalAndRemote(spaceAddress1 + "/" + testWorkerName, testWorkerName);
		}

		[TestMethod]
		public void TestWorkerLocalAndRemote2()
		{
			TestWorkerLocalAndRemote(spaceAddress1 + "/", null);
		}

		[TestMethod]
		public void TestWorkerLocalAndRemote3()
		{
			TestWorkerLocalAndRemote(spaceAddress1, null);
		}

		private XcoAppSpace CreateAppSpace(int port)
		{
			return XcoAppSpace.Configure.UsingService(new XcoTCPTransportService()).OnPort(port);
		}

		private void TestWorkerLocalAndRemote(string workerAddressStr, string workerName) //, bool wcfComm)
		{
			using (XcoAppSpace space1 = CreateAppSpace(port1),
							   space2 = CreateAppSpace(port2))
			{
				//Assert.IsTrue(spaceAddress1.Equals(space1.Address, StringComparison.OrdinalIgnoreCase));
				//Assert.IsTrue(spaceAddress2.Equals(space2.Address, StringComparison.OrdinalIgnoreCase));
				
				//run worker
				space1.RunWorker<TestWorkerContract, MyTestWorker>(workerName);
				MyTestWorker localWorker = (MyTestWorker)space1.Resolve<TestWorkerContract>(workerName);
				
				//test for local worker access
				localWorker.Post(1);
				Task.Delay(100).Wait();
				Assert.AreEqual(1, localWorker.intMsg);

				//connect to remote worker
				TestWorkerContract remoteWorker = //(workerUri != null ? 
					//space2.ConnectWorker<TestWorkerContract>(workerUri) : 
					space2.ConnectWorker<TestWorkerContract>(workerAddressStr); //);
				TestWorkerContract remoteWorker2 = space2.Resolve<TestWorkerContract>();
				Assert.AreSame(remoteWorker, remoteWorker2);

				//tests for remote worker access and remote port
				remoteWorker.Post(2);
				remoteWorker.Post("test");
				Task.Delay(100).Wait();
				PortSet<int, string> responsePort = new PortSet<int, string>();
				remoteWorker.Post(responsePort);
				Task.Delay(500).Wait();
				Assert.AreEqual(2, localWorker.intMsg);
				Assert.AreEqual("test", localWorker.strMsg);
				Assert.AreEqual(1, responsePort.P0.ItemCount);
				Assert.AreEqual(0, responsePort.P1.ItemCount);
				int postedInt = responsePort.P0.Receive(1000).Result;
				Assert.AreEqual(2, postedInt);
			}
		}

		[TestMethod]
		public void TestWorkerLocalOnly()
		{
			using (XcoAppSpace space1 = new XcoAppSpace())
			{
				//run worker
				space1.RunWorker<TestWorkerContract, MyTestWorker>(testWorkerName);
				MyTestWorker localWorker = (MyTestWorker)space1.Resolve<TestWorkerContract>(testWorkerName);

				//test for local worker access
				localWorker.Post(1);
				Task.Delay(100).Wait();
				Assert.AreEqual(1, localWorker.intMsg);

				//try to connect to remote worker
				try
				{
					TestWorkerContract remoteWorker = space1.ConnectWorker<TestWorkerContract>(spaceAddress2 + "/" + testWorkerName);
					Assert.Fail("XcoCommunicationException should have been thrown!");
				}
				catch (XcoCommunicationException)
				{
				}
				//space address should be null
				Assert.IsNull(space1.Address);
			}
		}

		[TestMethod]
		public void TestWorkerPreInstantiated1()
		{
			using (XcoAppSpace space = new XcoAppSpace())
			{
				var workerPre = new MyWorker();
				//space.Register<WorkerContract, MyWorker>();
				WorkerContract worker = space.RunWorker<WorkerContract>(workerPre);
				Assert.IsNotNull(worker);
				Assert.AreSame(workerPre, worker);
				Assert.AreSame(worker, space.Resolve<WorkerContract>());
			}
		}

		[TestMethod]
		public void TestWorker2PreInstantiated2()
		{
			using (XcoAppSpace space = new XcoAppSpace())
			{
				var workerPre = new MyWorker();
				//space.Register<WorkerContract, MyWorker>(testWorkerName);
				WorkerContract worker = space.RunWorker<WorkerContract>(workerPre, testWorkerName);
				Assert.IsNotNull(worker);
				Assert.AreSame(workerPre, worker);
				Assert.AreSame(worker, space.Resolve<WorkerContract>(testWorkerName));
			}
		}

		[TestMethod]
		public void TestWorkerStop()
		{
			using (XcoAppSpace space = new XcoAppSpace())
			{
				//register worker
				//space.Register<WorkerContract, MyWorker>(testWorkerName);
				WorkerContract worker = space.RunWorker<WorkerContract, MyWorker>(testWorkerName);
				Assert.IsNotNull(worker);
				Assert.IsInstanceOfType(worker, typeof(MyWorker));
				MyWorker mw = (MyWorker)worker;
				Assert.IsNotNull(space.Resolve<WorkerContract>(testWorkerName));
				//Assert.IsTrue(UnityContainerExtensions.CanResolveWorkerInstance(space.DefaultDIContainer, typeof(WorkerContract), testWorkerName));
				worker.Post("test");
				Task.Delay(100).Wait();
				Assert.AreEqual("test", mw.strMsg);

				//dispose worker
				space.StopWorker(worker);
				//WorkerContract newWorker = space.Resolve<WorkerContract>(testWorkerName);
				//Assert.AreNotSame(worker, newWorker);
				Assert.IsNull(space.Resolve<WorkerContract>(testWorkerName));
				//Assert.IsFalse(UnityContainerExtensions.CanResolveWorkerInstance(space.DefaultDIContainer, typeof(WorkerContract), testWorkerName));
				worker.Post("test2");
				Task.Delay(100).Wait();
				Assert.AreEqual("test", mw.strMsg); //ccr receiver tasks should have been unregistered
			}
		}

		[TestMethod]
		public void TestWorkerStop2()
		{
			using (XcoAppSpace space = new XcoAppSpace())
			{
				//register worker
				//space.Register<WorkerContract, MyWorker>(testWorkerName);
				WorkerContract worker = space.RunWorker<WorkerContract, MyWorker>(testWorkerName);
				Assert.IsNotNull(worker);
				Assert.IsInstanceOfType(worker, typeof(MyWorker));
				MyWorker mw = (MyWorker)worker;
				Assert.IsNotNull(space.Resolve<WorkerContract>(testWorkerName));
				//Assert.IsTrue(UnityContainerExtensions.CanResolveWorkerInstance(space.DefaultDIContainer, typeof(WorkerContract), testWorkerName));
				worker.Post("test");
				Task.Delay(100).Wait();
				Assert.AreEqual("test", mw.strMsg);

				//dispose worker
				space.StopWorker<WorkerContract>(testWorkerName);
				//WorkerContract newWorker = space.Resolve<WorkerContract>(testWorkerName);
				//Assert.AreNotSame(worker, newWorker);
				Assert.IsNull(space.Resolve<WorkerContract>(testWorkerName));
				//Assert.IsFalse(UnityContainerExtensions.CanResolveWorkerInstance(space.DefaultDIContainer, typeof(WorkerContract), testWorkerName));
				worker.Post("test2");
				Task.Delay(100).Wait();
				Assert.AreEqual("test", mw.strMsg); //ccr receiver tasks should have been unregistered
			}
		}

		[TestMethod]
		public void TestWorkerStop3()
		{
			using (XcoAppSpace space = new XcoAppSpace())
			{
				//register worker
				//space.Register<WorkerContract, MyWorker>();
				WorkerContract worker = space.RunWorker<WorkerContract, MyWorker>();
				Assert.IsNotNull(worker);
				Assert.IsInstanceOfType(worker, typeof(MyWorker));
				MyWorker mw = (MyWorker)worker;
				Assert.IsNotNull(space.Resolve<WorkerContract>());
				//Assert.IsTrue(UnityContainerExtensions.CanResolveWorkerInstance(space.DefaultDIContainer, typeof(WorkerContract), (string) null));
				worker.Post("test");
				Task.Delay(100).Wait();
				Assert.AreEqual("test", mw.strMsg);

				//dispose worker
				space.StopWorker<WorkerContract>();
				//WorkerContract newWorker = space.Resolve<WorkerContract>();
				//Assert.AreNotSame(worker, newWorker);
				Assert.IsNull(space.Resolve<WorkerContract>(testWorkerName));
				//Assert.IsFalse(UnityContainerExtensions.CanResolveWorkerInstance(space.DefaultDIContainer, typeof(WorkerContract), (string) null));
				worker.Post("test2");
				Task.Delay(100).Wait();
				Assert.AreEqual("test", mw.strMsg); //ccr receiver tasks should have been unregistered
			}
		}

		[TestMethod]
		public void TestWorkerStop4()
		{
			//dispose with remote communication
			using (XcoAppSpace space1 = new XcoAppSpace("tcp.port=" + port1),
				space2 = new XcoAppSpace("tcp.port=" + port2))
			{
				//register worker
				WorkerContract worker = space1.RunWorker<WorkerContract, MyWorker>();
				Assert.IsNotNull(space1.Resolve<WorkerContract>());
				//Assert.IsTrue(UnityContainerExtensions.CanResolveWorkerInstance(space1.DefaultDIContainer, typeof(WorkerContract), (string) null));
				//connect to worker
				WorkerContract remoteWorker = space2.ConnectWorker<WorkerContract>(spaceAddress1);
				Assert.IsNotNull(remoteWorker);
				//dispose worker
				space1.StopWorker<WorkerContract>();
				Assert.IsNull(space1.Resolve<WorkerContract>(testWorkerName));
				//Assert.IsFalse(UnityContainerExtensions.CanResolveWorkerInstance(space1.DefaultDIContainer, typeof(WorkerContract), (string) null));
				//try again to connect to worker
				try
				{
					remoteWorker = space2.ConnectWorker<WorkerContract>(spaceAddress1);
					Assert.Fail();
				}
				catch (XcoCommunicationException)
				{
				}
			}
		}

		[TestMethod]
		public void TestWorkerUnpublished()
		{
			using (XcoAppSpace space1 = new XcoAppSpace("tcp.port=" + port1),
				space2 = new XcoAppSpace("tcp.port=" + port2))
			{
				//register worker
                WorkerContract worker = space1.RunWorker<WorkerContract, MyWorker>(PublishMode.Unpublished);
				//try to connect to worker
				try
				{
					WorkerContract remoteWorker = space2.ConnectWorker<WorkerContract>(spaceAddress1);
					Assert.Fail();
				}
				catch (XcoCommunicationException)
				{
				}
			}
		}

		[TestMethod]
		public void TestWorkerProxy()
		{
			//space communicates over the published worker proxy of another space
			using (XcoAppSpace space1 = new XcoAppSpace("tcp.port=" + port1),
				space2 = new XcoAppSpace("tcp.port=" + port2),
				space3 = new XcoAppSpace("tcp.port=" + port3))
			{
				WorkerContract worker = space1.RunWorker<WorkerContract, MyWorker>();
				WorkerContract workerProxy1 = space2.ConnectWorker<WorkerContract>(PublishMode.Published, spaceAddress1);
				WorkerContract workerProxy2 = space3.ConnectWorker<WorkerContract>(spaceAddress2);
				//test with message
				workerProxy2.Post(123);
				Task.Delay(1000).Wait();
				MyWorker mw = (MyWorker)worker;
				Assert.AreEqual(123, mw.intMsg);
			}
		}

		[TestMethod]
		public void TestWorkerProxyUnpublished()
		{
			//by default worker proxies should not be published
			using (XcoAppSpace space1 = new XcoAppSpace("tcp.port=" + port1),
				space2 = new XcoAppSpace("tcp.port=" + port2),
				space3 = new XcoAppSpace("tcp.port=" + port3))
			{
				WorkerContract worker = space1.RunWorker<WorkerContract, MyWorker>();
				WorkerContract workerProxy1 = space2.ConnectWorker<WorkerContract>(spaceAddress1);
				try
				{
					WorkerContract workerProxy2 = space3.ConnectWorker<WorkerContract>(spaceAddress2);
					Assert.Fail();
				}
				catch (XcoCommunicationException)
				{
				}
			}
		}


		[TestMethod]
		public void TestWorkerHostWithMultipleCommServices()
		{
			using (
				XcoAppSpace space1 = XcoAppSpace.Configure
					.UsingService(new XcoTCPTransportService()).OnPort(port1).WithName("tcp").AsDefault()
					.UsingService(new XcoTCPTransportService()).OnPort(port1b).WithName("tcp2"),
				space2tcp = XcoAppSpace.Configure.UsingService(new XcoTCPTransportService()).OnPort(port2),
				space3tcp2 = XcoAppSpace.Configure.UsingService(new XcoTCPTransportService()).OnPort(port3))
			{
				//run worker
				space1.RunWorker<TestWorkerContract, MyTestWorker>(testWorkerName);
				MyTestWorker localWorker = (MyTestWorker)space1.Resolve<TestWorkerContract>(testWorkerName);

				//remote worker over tcp
				TestWorkerContract remoteWorkerTcp = space2tcp.ConnectWorker<TestWorkerContract>(spaceAddress1 + "/" + testWorkerName);
				//tests for remote worker access and remote port
				remoteWorkerTcp.Post(1);
				remoteWorkerTcp.Post("testTcp");
				Task.Delay(100).Wait();
				PortSet<int, string> responsePort = new PortSet<int, string>();
				remoteWorkerTcp.Post(responsePort);
				Task.Delay(100).Wait();
				Assert.AreEqual(1, localWorker.intMsg);
				Assert.AreEqual("testTcp", localWorker.strMsg);
				Assert.AreEqual(1, responsePort.P0.ItemCount);
				Assert.AreEqual(0, responsePort.P1.ItemCount);
				int postedInt = responsePort.P0.Receive(1000).Result;
				Assert.AreEqual(1, postedInt);

				//remote worker over wcf
				TestWorkerContract remoteWorkerWcf = space3tcp2.ConnectWorker<TestWorkerContract>(spaceAddress1b + "/" + testWorkerName);
				//tests for remote worker access and remote port
				remoteWorkerWcf.Post(2);
				remoteWorkerWcf.Post("testWcf");
				Task.Delay(100).Wait();
				responsePort = new PortSet<int, string>();
				remoteWorkerWcf.Post(responsePort);
				Task.Delay(100).Wait();
				Assert.AreEqual(2, localWorker.intMsg);
				Assert.AreEqual("testWcf", localWorker.strMsg);
				Assert.AreEqual(1, responsePort.P0.ItemCount);
				Assert.AreEqual(0, responsePort.P1.ItemCount);
				postedInt = responsePort.P0.Receive(1000).Result;
				Assert.AreEqual(2, postedInt);
			}
		}

		[TestMethod]
		public void TestWorkerConnectWithMultipleCommServices()
		{
			using (
				XcoAppSpace space1 = XcoAppSpace.Configure
					.UsingService<XcoTCPTransportService>().OnPort(port1).WithName("tcp").AsDefault()
					.UsingService<XcoTCPTransportService>().OnPort(port1b).WithName("tcp2"),
				space2tcp = XcoAppSpace.Configure.UsingService<XcoTCPTransportService>().OnPort(port2),
				space3wcf = XcoAppSpace.Configure.UsingService<XcoTCPTransportService>().OnPort(port3))
			{
				//run workers at space 2 and 3
				MyTestWorker localWorkerTcp = (MyTestWorker)space2tcp.RunWorker<TestWorkerContract, MyTestWorker>("1");
				MyTestWorker localWorkerWcf = (MyTestWorker)space3wcf.RunWorker<TestWorkerContract, MyTestWorker>("2");
				
				//connect to remote worker at space 2 over tcp (default)
				TestWorkerContract remoteWorker = space1.ConnectWorker<TestWorkerContract>(spaceAddress2 + "/1", "1");
				//tests for remote worker access and remote port
				remoteWorker.Post(1);
				remoteWorker.Post("testTcp");
				Task.Delay(100).Wait();
				PortSet<int, string> responsePort = new PortSet<int, string>();
				remoteWorker.Post(responsePort);
				Task.Delay(100).Wait();
				Assert.AreEqual(1, localWorkerTcp.intMsg);
				Assert.AreEqual("testTcp", localWorkerTcp.strMsg);
				Assert.AreEqual(1, responsePort.P0.ItemCount);
				Assert.AreEqual(0, responsePort.P1.ItemCount);
				int postedInt = responsePort.P0.Receive(1000).Result;
				Assert.AreEqual(1, postedInt);

				//remote worker at space 3 over wcf
				remoteWorker = space1.ConnectWorker<TestWorkerContract>("tcp2", spaceAddress3 + "/2", "2");
				//tests for remote worker access and remote port
				remoteWorker.Post(2);
				remoteWorker.Post("testWcf");
				Task.Delay(100).Wait();
				responsePort = new PortSet<int, string>();
				remoteWorker.Post(responsePort);
				Task.Delay(100).Wait();
				Assert.AreEqual(2, localWorkerWcf.intMsg);
				Assert.AreEqual("testWcf", localWorkerWcf.strMsg);
				Assert.AreEqual(1, responsePort.P0.ItemCount);
				Assert.AreEqual(0, responsePort.P1.ItemCount);
				postedInt = responsePort.P0.Receive(1000).Result;
				Assert.AreEqual(2, postedInt);
			}
		}

		[TestMethod]
		public void TestWithNotExistingCommService()
		{
			using (
				XcoAppSpace space1 = XcoAppSpace.Configure
					.UsingService(new XcoTCPTransportService()).OnPort(port1).WithName("tcp").AsDefault()
					.UsingService(new XcoTCPTransportService()).OnPort(port1b).WithName("tcp2"),
				space2 = XcoAppSpace.Configure.UsingService(new XcoTCPTransportService()).OnPort(port2))
			{
				//run worker
				space1.RunWorker<TestWorkerContract, MyTestWorker>(testWorkerName);
				MyTestWorker localWorker = (MyTestWorker)space1.Resolve<TestWorkerContract>(testWorkerName);

				//try to connect to remote worker
				Assert.ThrowsException<XcoCommunicationException>(() =>
				{
					TestWorkerContract remoteWorkerTcp = space2.ConnectWorker<TestWorkerContract>("unknownCommService", spaceAddress1 + "/" + testWorkerName);
				});

			}
		}

		[TestMethod]
		public void TestSpaceInfo()
		{
			XcoTCPTransportService comm1 = new XcoTCPTransportService();
			XcoTCPTransportService comm2 = new XcoTCPTransportService();
			using (
				XcoAppSpace space1 = XcoAppSpace.Configure
					.UsingService(comm1).OnPort(port1).WithName("tcp").AsDefault()
					.UsingService(comm2).OnPort(port1b).WithName("tcp2"),
				space2 = XcoAppSpace.Configure.UsingService(new XcoTCPTransportService()).OnPort(port2))
			{
				//check communication services information
				Assert.AreEqual(2, space1.Info.TransportServices.Count());
				Assert.AreEqual(1, space1.Info.TransportServices.Count(cs => cs.IsDefault && cs.Name == "tcp" && cs.Service == comm1));
				Assert.AreEqual(1, space1.Info.TransportServices.Count(cs => !cs.IsDefault && cs.Name == "tcp2" && cs.Service == comm2));
				
				//run some workers
				int initialWorkerCount = space1.Info.Workers.Count();
				TestWorkerContract worker = space1.RunWorker<TestWorkerContract, MyTestWorker>("w1");
				TestWorkerContract worker2 = space1.RunWorker<TestWorkerContract, MyTestWorker>("w2");
				space2.RunWorker<TestWorkerContract, MyTestWorker>("w3");
				
				//check number of connect calls (must increase when ConnectWorker is called, must not increase when messages are posted)
				Assert.AreEqual(0, space2.Info.Workers.First(w => w.Worker is TestWorkerContract).NumberOfConnections);
				TestWorkerContract worker3 = space1.ConnectWorker<TestWorkerContract>(spaceAddress2 + "/w3", "w3");
				Assert.AreEqual(1, space2.Info.Workers.First(w => w.Worker is TestWorkerContract).NumberOfConnections);
				worker3.Post("test");
				worker3.Post(123);
				Task.Delay(1000).Wait();
				Assert.AreEqual(1, space2.Info.Workers.First(w => w.Worker is TestWorkerContract).NumberOfConnections);
				
				//check worker information (3 registered workers + resolve worker)
				Assert.AreEqual(initialWorkerCount + 3, space1.Info.Workers.Count());
				Assert.AreEqual(1, space1.Info.Workers.Count(w => w.Name == "w1" && w.IsPublished && !w.IsRemote && w.Worker == worker && w.RemoteAddress == null && w.TransportServiceName == null));
				Assert.AreEqual(1, space1.Info.Workers.Count(w => w.Name == "w2" && w.IsPublished && !w.IsRemote && w.Worker == worker2 && w.RemoteAddress == null && w.TransportServiceName == null));
				Assert.AreEqual(1, space1.Info.Workers.Count(w => w.Name == "w3" && !w.IsPublished && w.IsRemote && w.Worker == worker3 && w.RemoteAddress == (spaceAddress2 + "/w3") && w.TransportServiceName == "tcp"));

				//check port information
				Assert.IsFalse(worker.P0.GetPortInfo().IsRemotePort);
				Assert.IsTrue(worker3.P0.GetPortInfo().IsRemotePort);
				Assert.AreEqual(spaceAddress2, worker3.P0.GetPortInfo().RemoteAddress);
				Assert.AreEqual("tcp", worker3.P0.GetPortInfo().TransportServiceName);
				//Assert.AreSame(comm1, worker3.P0.GetPortInfo().CommService.Service);
				//Assert.IsTrue(worker3.P0.GetPortInfo().CommService.IsDefault);

				//dispose workers and check if info was removed
				space1.StopWorker(worker);
				Assert.AreEqual(0, space1.Info.Workers.Count(w => w.Worker == worker));
				space1.StopWorker(worker3);
				Assert.AreEqual(0, space1.Info.Workers.Count(w => w.Worker == worker3));
				Assert.AreEqual(2, space1.Info.Workers.Count());
			}
		}

		[TestMethod]
		public void TestInstantiateWithConfigString_Tcp()
		{
			using (XcoAppSpace space = new XcoAppSpace("tcp.port=9000;tcp.name=tcpservicename"))
			{
				Assert.AreEqual(1, space.Info.TransportServices.Count());
				var commServiceInfo = space.Info.TransportServices.First();
				Assert.AreEqual(9000, ((XcoTCPTransportService)commServiceInfo.Service).Port);
				Assert.AreEqual("tcpservicename", commServiceInfo.Name);
				Assert.IsTrue(commServiceInfo.IsDefault);
			}
		}

		[TestMethod]
		public void TestInstantiateWithConfigString_Error()
		{
			Assert.ThrowsException<XcoConfigurationException>(() =>
			{
				//invalid config value for log.level
				using (XcoAppSpace space = new XcoAppSpace("tcp.port=bla"))
				{
				}
			});
			
		}

		[TestMethod]
		public void TestInstantiateWithConfigString_Empty()
		{
			//should start without remote communication
			using (XcoAppSpace space = new XcoAppSpace(""))
			{
				Assert.AreEqual(0, space.Info.TransportServices.Count());
			}
		}

		[TestMethod]
		public void TestInstantiateWithConfigString_Error2()
		{
			Assert.ThrowsException<XcoConfigurationException>(() =>
			{
				//invalid config value for tcp.port
				using (XcoAppSpace space = new XcoAppSpace("tcp.port=-1"))
				{
				}
			});
			
		}

		//[TestMethod]
		//public void TestInstantiateWithConfigStringAndFluentConfig()
		//{
		//	XcoTCPTransportService commService = new XcoTCPTransportService(port1); 
		//	using (XcoAppSpace space = XcoAppSpace.ConfigureWithConfigString("ccr.threadcount=1").UsingService(commService))
		//	{
		//		Assert.AreEqual(1, space.DefaultDispatcher.WorkerThreadCount);
		//		Assert.AreEqual(1, space.Info.TransportServices.Count());
		//		Assert.AreEqual(commService, space.Info.TransportServices.First().Service);
		//	}
		//}
	}
}
